/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.weso.acota.dao;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeIterator;
import org.weso.acota.enhacer.GoogleEnhancer;
import org.weso.acota.to.ProviderTO;
import org.weso.acota.to.RequestSuggestionTO;
import org.weso.acota.to.SuggestionTO;
import org.weso.acota.to.TagTO;
import org.weso.acota.utils.DocumentBuilderHelper;

/**
 *
 * @author chema, weena
 */
public class SuggestGoogleDAOImpl implements SuggestDAO {

	private static String googleUrl = "http://google.com/complete/search?output=toolbar&q=";
    private static ProviderTO defaultProvider = new ProviderTO("Google Enhancer"); //FIXME
    protected static Logger logger = Logger.getLogger(GoogleEnhancer.class);
    protected static int relevance =3;
    private RequestSuggestionTO request;
	private SuggestionTO suggest;
	
    @SuppressWarnings({ "unchecked", "rawtypes", "static-access" })
	public SuggestionTO suggest(RequestSuggestionTO doRequest) throws Exception {
    	logger.debug("Initialize variables");
        request = doRequest;
        suggest = request.getSuggestions();
        suggest.setResource(doRequest.getResource());
       
        logger.info("Doing request to Google API");
		NodeIterator it;
		//Check if there is another tag with the same label
		Iterator labels = suggest .getLabels().entrySet().iterator();
		while (labels.hasNext()) {
			Map.Entry label = (Map.Entry)labels.next();
			URL url = new URL(this.googleUrl + label.getKey().toString());
			logger.debug("Conect to google complete API");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("Accept", "application/xml");
            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK
                    && connection.getContentType().contains("text/xml")){
            	logger.debug("Get result of request to google complete API");
            	InputStream is = connection.getInputStream();
            	//buffered response to correct encoding
            	BufferedReader rd = new BufferedReader(new InputStreamReader(is, "ISO-8859-1"));
                String line;
                StringBuffer response = new StringBuffer(); 
                while((line = rd.readLine()) != null) {
                  response.append(line);
                  response.append('\n');
                }
                rd.close();
                //XML
                Document result = DocumentBuilderHelper.getDocumentFromString(response.toString());
                it = org.apache.xpath.XPathAPI.selectNodeIterator(result, "//suggestion/@data");
                Node n = it.nextNode();
                logger.debug("Add new tags to suggestions");
                while(n != null){
                	//Add new tag
                	TagTO tag = new TagTO();
                	tag.setLabel(n.getNodeValue());
                	tag.setProvider(defaultProvider);
                	tag.setTagged(this.request.getResource());
                	suggest.getTags().add(tag);
                	n = it.nextNode();
                }
            }
		}
		
		logger.debug("Add labels and weight to suggestions");
		for(TagTO tag: suggest.getTags()){
			if(tag.getProvider().equals(defaultProvider)){
            	if(suggest .getLabels().containsKey(tag.getLabel())){
            		//Check if there is another tag with the same label
    				Iterator itr = suggest .getLabels().entrySet().iterator();
    				while (itr.hasNext()) {
						Map.Entry e = (Map.Entry)itr.next();
    					if(e.getKey().equals(tag.getLabel())){
    						int valor = (Integer) e.getValue();
    						valor += relevance;
    						e.setValue(valor);
    					}
    				}	
            	}else{
            		suggest.getLabels().put(tag.getLabel(), relevance);
            	}
			}
		}
        return suggest;
    }
    
	public ProviderTO getProvider() {
		logger.info("Display provider name");
		return defaultProvider;
	}

}
